package org.freeswitch.esl.client.test;

import lombok.extern.slf4j.Slf4j;
import org.freeswitch.esl.client.IEslEventListener;
import org.freeswitch.esl.client.transport.event.EslEventHeaderNames;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.LongAdder;

/**
 * @author quehailin
 */
@Slf4j
@Component
public class FsClientUtils {

    public static FsProperties fsProperties;
    private static LongAdder RECEIVE_EVENT_NUM = null, DEAL_EVENT_NUM = null;

    /**
     * 创建FsClient<br>
     * 由于调用close方法不会让JVM删除FsClient，因此先要判断client是否为空，为空就创建，否则重新connect
     *
     * @param client       FsClient对象，如果为空，则创建，否则重新connect
     * @param fs FsClient配置
     * @return FsClient对象，如未连接成功，也会返回对象，只是未连接
     */
    public static FsClient createClient(FsClient client, FsProperties.Fs fs) {
        if (client == null) {
            client = new FsClient();
        }

        try {
            client.connect(fs.getHost(), fs.getPort(), fs.getPassword(), fs.getTimeout());
            // 因为这是新的连接，先设置心跳为当前时间
            setLastHeartbeatTime(client, System.currentTimeMillis());
            return client;
        } catch (Exception e) {
            e.printStackTrace();
            close(client);
        }
        return client;
    }

    /**
     * 设置心跳时间过滤器
     *
     * @param client FsClient对象
     */
    public static void setHeartbeatEventFilter(FsClient client) {
        if (!canSend(client)) {
            return;
        }
        cancelEventSubscriptions(client);
//        client.addEventFilter(EslEventHeaderNames.EVENT_NAME, FsEventType.HEARTBEAT.name());
        setEventSubscriptions(client);
    }

    /**
     * 设置事件过滤器
     *
     * @param client       FsClient对象
     * @param fsEventTypes 事件集合，为空时表示不过滤
     */
    public static void setEventFilter(FsClient client, FsEventType... fsEventTypes) {
        if (!canSend(client)) {
            return;
        }
        cancelEventSubscriptions(client);
        if (fsEventTypes != null) {
            for (FsEventType fsEventType : fsEventTypes) {
                client.addEventFilter(EslEventHeaderNames.EVENT_NAME, fsEventType.name());
            }
        }
        setEventSubscriptions(client);
    }

    /**
     * 取消事件订阅
     *
     * @param client FsClient对象
     */
    private static void cancelEventSubscriptions(FsClient client) {
        if (!canSend(client)) {
            return;
        }
        client.cancelEventSubscriptions();
    }

    private static synchronized void setReceiveEventNum() {
        if (log.isDebugEnabled()) {
            if (RECEIVE_EVENT_NUM == null) {
                RECEIVE_EVENT_NUM = new LongAdder();
            }
            RECEIVE_EVENT_NUM.add(1);
            log.debug("累计收到消息数量:{}", RECEIVE_EVENT_NUM);
        }
    }

    private static synchronized void setDealEventNum() {
        if (log.isDebugEnabled()) {
            if (DEAL_EVENT_NUM == null) {
                DEAL_EVENT_NUM = new LongAdder();
            }
            DEAL_EVENT_NUM.add(1);
            log.debug("累计处理消息数量:{}", DEAL_EVENT_NUM);
        }
    }

    /**
     * 删除所有事件监听规则
     *
     * @param client FsClient对象
     */
    public static void deleteAllEventFilter(FsClient client) {
        if (!canSend(client)) {
            return;
        }
        for (FsEventType fsEventType : FsEventType.values()) {
            client.deleteEventFilter(EslEventHeaderNames.EVENT_NAME, fsEventType.name());
        }
    }

    /**
     * 设置事件监听
     *
     * @param fsClient          FsClient对象
     * @param iEslEventListener FsClient监听
     */
    private static void setEventListener(FsClient fsClient, IEslEventListener iEslEventListener) {
        if (!canSend(fsClient)) {
            return;
        }
        fsClient.cancelEventSubscriptions();
        fsClient.addEventListener(iEslEventListener);
        setEventSubscriptions(fsClient);
    }

    /**
     * 订阅你需要的ESl事件，all是订阅所有事件。<br>
     * 具体事件列表请看https://freeswitch.org/confluence/display/FREESWITCH/Event+List
     *
     * @param fsClient FsClient对象
     */
    private static void setEventSubscriptions(FsClient fsClient) {
        if (!canSend(fsClient)) {
            return;
        }
        fsClient.setEventSubscriptions("plain", "all");
    }

    /**
     * 设置FsClient收到最后一次心跳包的时间
     *
     * @param fsClient          FsClient对象
     * @param lastHeartbeatTime 最后一次心跳包的时间，时间戳，毫秒
     */
    public static void setLastHeartbeatTime(FsClient fsClient, long lastHeartbeatTime) {
        if (fsClient == null) {
            return;
        }
        fsClient.lastHeartbeatTime = lastHeartbeatTime;
    }

    /**
     * 关闭客户端连接<br>
     * <font color="#DC143C">注意：关闭客户端，FsClient不会被JVM清除</font>
     *
     * @param client FsClient对象
     */
    public static void close(FsClient client) {
        try {
            if (client != null && client.canSend()) {
                client.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 验证Client心跳是否过期
     *
     * @param fsClient FsClient对象
     * @return true：过期     false：未过期
     */
    private static boolean checkClientHeartTimeExpire(FsClient fsClient) {
        if (fsClient == null) {
            return true;
        }
        return false;
    }

    /**
     * 验证连接是否有效
     *
     * @param fsClient FsClient对象
     * @return true：有效  false：无效
     */
    public static boolean canSend(FsClient fsClient) {
        return !checkClientHeartTimeExpire(fsClient) && fsClient.canSend();

    }

    @Autowired
    public void setFsProperties(FsProperties fsProperties) {
        FsClientUtils.fsProperties = fsProperties;
    }


}
